package middlewares

import (
	"github.com/gin-gonic/gin"
	"github.com/golang-jwt/jwt/v5"
	"github.com/webook/internal/web"
	"log"
	"net/http"
	"strings"
	"time"
)

type LoginJWTMiddlwareBuilDer struct {
}

func (m *LoginJWTMiddlwareBuilDer) CheckLogin() gin.HandlerFunc {
	return func(ctx *gin.Context) {
		path := ctx.Request.URL.Path
		if path == "/users/signup" || path == "/users/login" {
			//不需要登录校验
			return
		}
		//根据约定，token在Authorization 头部
		//Bearer XXXX
		authCode := ctx.GetHeader("Authorization")
		if authCode == "" {
			//没有登录,没有token
			ctx.AbortWithStatus(http.StatusUnauthorized)
			return
		}
		segs := strings.Split(authCode, " ")
		if len(segs) != 2 {
			//没登陆，Authoriztion中的内容是乱传的
			ctx.AbortWithStatus(http.StatusUnauthorized)
		}
		tokenStr := segs[1]
		var uc web.UserClaims
		token, err := jwt.ParseWithClaims(tokenStr, &uc, func(token *jwt.Token) (interface{}, error) {
			return web.JwtKey, nil
		})
		if err != nil {
			// token 不对，token是伪造的
			ctx.AbortWithStatus(http.StatusUnauthorized)
			return
		}

		if !token.Valid {
			// token 解析出来了，但是token 非法或者过期
			ctx.AbortWithStatus(http.StatusUnauthorized)
			return
		}
		expireTime := uc.ExpiresAt
		if expireTime.Before(time.Now()) {
			ctx.AbortWithStatus(http.StatusUnauthorized)
			return
		}
		//剩余过期时间 < 50 s
		if expireTime.Sub(time.Now()) < time.Second*50 {
			uc.ExpiresAt = jwt.NewNumericDate(time.Now().Add(time.Minute))
			tokenStr, err = token.SignedString(web.JwtKey)
			ctx.Header("x-jwt-token", tokenStr)
			if err != nil {
				//这边不要中断，因为仅仅是过期时间没有刷新
				log.Println(err)
			}
		}
		ctx.Set("user", uc)
	}
}
